<?php

require_once(dirname(__FILE__).'/ApiPoolError.php');
require_once(dirname(__FILE__).'/ApiPoolProtocol.php');
require_once(dirname(__FILE__).'/ApiPoolRequest.php');
require_once(dirname(__FILE__).'/ApiPoolResponse.php');
require_once(dirname(__FILE__).'/ApiPoolClient.php');
require_once(dirname(__FILE__).'/ApiPoolCrypt.php');

class ApiPool
{
	private static $requestSrc;
	
	public $apiPoolClient = null;
	
	public $crypter = null;
	
	public $defaultParams = null;
	
	public $id = null;
	
	public static function setRequestSrc($requestSrc) {
		self::$requestSrc = $requestSrc;
	}
	
	public function __construct() {
	}
	
	public function setServer($host, $port, $long_connect = false) {
		if ($long_connect) {
			$this->apiPoolClient = new ApiPoolClientLong();
		} else {
			$this->apiPoolClient = new ApiPoolClientShort();
		}
		$this->apiPoolClient->setServer($host,$port);
	}
	
	public function setCrypter($type, $key) {
		$this->crypter = ApiPoolCryptFactory::newCrypter($type, $key);
	}
	
	public function setTimeout($timeout) {
		$this->apiPoolClient->setTimeout($timeout, $timeout);
	}
	
	public function setDefaultParams($default) {
		$this->defaultParams = $default;
	}
	
	protected function generateId() {
		$id = explode(" ", microtime(false));
		$id = intval($id[0] * 1000 + ($id[1] % 3600) * 1000);
		$this->id = $id;
		return $id;
	}
	
	public function getLastId() {
		return $this->id;
	}
	
	/*
		@$service_method		Shorten. MakeShortUrlByLongUrl
		@args 						array('url'=>'http://zhidao.baidu.com/��)
		@timeout					timeout of million seconds

	*/
	public function request($service_method, $param_list = null, $timeout = 1000, $notify = false) {
		if ($notify == true) {
			return $this->notify($service_method, $param_list, $timeout);
		}
		
		$request = new ApiPoolRequest();
		$response = new ApiPoolResponse();
		
		$params = $param_list;
		$default = $this->defaultParams;
		if (is_array($params) && is_array($default)) {
			foreach ($default as $key => $value) {
				if (! array_key_exists($key, $params)) {
					$params[$key] = $value;
					//array_push($params, array($key => $value));
				}
			}
		}
		
		$request_src = self::$requestSrc;
		$service = explode(".", $service_method);
		$service_name = $service[0];
		$api_name = $service[1];
		if (! ApiPoolRequest::create($request, $request_src, $service_name, $api_name, $params)) {
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_REQ);
			return $response;
		}
		
		$request->setId($this->generateId());
		
		if (! is_null($this->crypter) && ! $this->crypter->encryptRequest($request)) {
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_ENCRYPT);
			return $response;
		}
		
		$request_pack = $request->makePackage();
		if ($request_pack == null) {
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_REQ);
			return $response;
		}
		
		$this->setTimeout($timeout / 1000);
		
		$response_pack = $this->apiPoolClient->sendReceive($request_pack);
		if($response_pack === false){
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_RPC, $this->apiPoolClient->getLastError());
			return $response;
		}
		
		if (! $response->parsePackage($response_pack)) {
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_RES);
			return $response;
		}
		
		if (! is_null($this->crypter) && ! $this->crypter->decryptResponse($response)) {
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_DECRYPT);
			return $response;
		}
		
		return $response;
	}
	
	/*
		@$service_method		Shorten. MakeShortUrlByLongUrl
		@args 						array('url'=>'http://zhidao.baidu.com/��)
		@timeout					timeout of million seconds

	*/
	public function notify($service_method, $param_list = null, $timeout = 1000) {
		$request = new ApiPoolRequest();
		$response = new ApiPoolResponse();
		
		$params = $param_list;
		$default = $this->defaultParams;
		if (is_array($params) && is_array($default)) {
			foreach ($default as $key => $value) {
				if (! array_key_exists($key, $params)) {
					$params[$key] = $value;
					//array_push($params, array($key => $value));
				}
			}
		}
		
		$request_src = self::$requestSrc;
		$service = explode(".", $service_method);
		$service_name = $service[0];
		$api_name = $service[1];
		if (! ApiPoolRequest::create($request, $request_src, $service_name, $api_name, $params)) {
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_REQ);
			return $response;
		}
		
		$request->setId(null);
		
		if (! is_null($this->crypter) && ! $this->crypter->encryptRequest($request)) {
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_ENCRYPT);
			return $response;
		}
		
		$request_pack = $request->makePackage();
		if ($request_pack == null) {
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_REQ);
			return $response;
		}
		
		$this->setTimeout($timeout / 1000);
		$response_pack = $this->apiPoolClient->send($request_pack);
		if($response_pack === false){
			$response->setErrorAndErrorInfo(ApiPoolError::ERR_RPC, $this->apiPoolClient->getLastError());
			return $response;
		}

		return $response;
	}
}

?>
